package org.radsimplified.genapp.metadata;

import org.radsimplified.genapp.Helper;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class BizEntity {

	protected String name;
    protected String plural;
    protected String tableName;
    protected String title;
    protected String module;
    protected Attribute identifierColumn;
    protected String orderBy;
    protected Boolean customView = false;
    protected Boolean customEdit = false;
    protected Boolean customList = false;
    protected List<Attribute> attributes = new ArrayList<Attribute>();
    protected List<Operation> operations = new ArrayList<Operation>();
    protected List<UniqueKey> uniqueKeys = new ArrayList<UniqueKey>();

    protected List<BizEntity> selectableEntities = new ArrayList<BizEntity>();
    protected List<BizEntity> selectableEditableEntities = new ArrayList<BizEntity>();
    protected List<BizEntity> selectableSearchableEntities = new ArrayList<BizEntity>();
    
	public List<BizEntity> getSelectableEntities() {
		return selectableEntities;
	}
	
	public void addSelectableEntity(BizEntity entity) {
		for (BizEntity e: selectableEntities)
			if (e.name.equals(entity.name))
				return;
		selectableEntities.add(entity);
	}

	public List<BizEntity> getSelectableEditableEntities() {
		return selectableEditableEntities;
	}

	public void addSelectableEditableEntity(BizEntity entity) {
		for (BizEntity e: selectableEditableEntities)
			if (e.name.equals(entity.name))
				return;
		selectableEditableEntities.add(entity);
	}

	public List<BizEntity> getSelectableSearchableEntities() {
		return selectableSearchableEntities;
	}

	public void addSelectableSearchableEntity(BizEntity entity) {
		for (BizEntity e: selectableSearchableEntities)
			if (e.name.equals(entity.name))
				return;
		selectableSearchableEntities.add(entity);
	}

	public String getModule() {
		return module;
	}

	public void setModule(String module) {
		this.module = module;
	}

	public Boolean getCustomView() {
		return customView;
	}

	public void setCustomView(Boolean customView) {
		this.customView = customView;
	}

	public Boolean getCustomEdit() {
		return customEdit;
	}

	public void setCustomEdit(Boolean customEdit) {
		this.customEdit = customEdit;
	}

	public Boolean getCustomList() {
		return customList;
	}

	public void setCustomList(Boolean customList) {
		this.customList = customList;
	}

	public String getOrderBy() {
		return orderBy;
	}

	public void setOrderBy(String orderBy) {
		this.orderBy = orderBy;
	}

	public void setName(String name) {
		this.name = name != null && name.equals("") ? null : name;
    }

	public String getName() {
		return name;
	}

    public void setPlural(String plural) {
		this.plural = plural != null && plural.equals("") ? null : plural;
    }

	public String getPlural() {
		return plural;
	}

    public void setTableName(String tableName) {
		this.tableName = tableName != null && tableName.equals("") ? null : tableName;
    }

	public String getTableName() {
		if (tableName == null || tableName.trim().equals(""))
			return name;
		return tableName;
	}

    public void setTitle(String title) {
		this.title = title != null && title.equals("") ? null : title;
    }

	public String getTitle() {
		return title;
	}

    public void setIdentifierColumn(Attribute identifierColumn) {
		this.identifierColumn = identifierColumn;
    }

	public Attribute getIdentifierColumn() {
		return identifierColumn;
	}

    public void addAttribute(Attribute obj) {
    	attributes.add(obj);
    	obj.setEntity((BizEntity)this);
    }
    
    public void removeAttributes(Iterator<Attribute> iter, Attribute obj) {
    	obj.setEntity(null);
    	iter.remove();
    }

	public List<Attribute> getAttributes() {
		return attributes;
	}

    public void addOperation(Operation obj) {
    	operations.add(obj);
    	obj.setEntity((BizEntity)this);
    }
    
    public void removeOperations(Iterator<Operation> iter, Operation obj) {
    	obj.setEntity(null);
    	iter.remove();
    }

	public List<Operation> getOperations() {
		return operations;
	}

    public void addUniqueKey(UniqueKey obj) {
    	uniqueKeys.add(obj);
    	obj.setEntity((BizEntity)this);
    }
    
    public void removeUniqueKeys(Iterator<UniqueKey> iter, UniqueKey obj) {
    	obj.setEntity(null);
    	iter.remove();
    }

	public List<UniqueKey> getUniqueKeys() {
		return uniqueKeys;
	}

	@Override
	public String toString() {
		return name;
	}

	public Attribute getAttribute(String attributeName) {
		for (Attribute attribute: attributes)
			if (attribute.getName().equals(attributeName))
				return attribute;
		return null;
	}

	public String getModuleUrl() {
		return module;
	}

	public String getCamelName() {
		return Helper.toCamelCase(name);
	}

	public boolean getMultipart() {
		return true;
	}
	
	public String getItemValue() {
		return identifierColumn == null ? "id" : identifierColumn.getName();
	}
	
	public String getOrderByStmt() {
		if (orderBy == null || orderBy.equals(""))
			return null;
		StringBuilder stmt = new StringBuilder("c");
		String[] clauses = orderBy.split(",");
		for (String clause : clauses) {
			clause = clause.trim();
			int i = clause.indexOf(" ");
			
			boolean asc = true;
			String property;
			if (i < 0)
				property = clause;
			else {
				property = clause.substring(0, i);
				if (clause.endsWith("desc"))
					asc = false;
			}
			
			stmt.append(".addOrder(Order." + (asc ? "asc" : "desc") + "(\"" + property + "\"))");
		}
		return stmt.toString();
	}
	
	public String getUniqueConstraints() {
		StringBuilder uc = new StringBuilder();
		int i = 0;
		for (UniqueKey key: getUniqueKeys()) {
			i += 1;
			uc.append((i > 1 ? ", " : "") + "@UniqueConstraint(columnNames={" + key.getColumns() + "})");
		}
		return uc.toString();
	}
	
	
}
